/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.repository.dbcolumninfo.repoproccessor;

import com.inspur.edp.cef.api.repository.readerWriter.ICefReader;
import com.inspur.edp.cef.entity.entity.AssoInfoBase;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.repository.adaptor.EntityRelationalAdaptor;
import com.inspur.edp.cef.repository.adaptoritem.BaseAdaptorItem;
import com.inspur.edp.cef.repository.adaptoritem.dbprocessor.DbProcessor;
import com.inspur.edp.cef.repository.dbcolumninfo.DbColumnInfo;
import com.inspur.edp.cef.repository.readerwriter.CefMappingReader;
import com.inspur.edp.cef.repository.repo.BaseRootRepository;
import com.inspur.edp.cef.spi.entity.IAuthFieldValue;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.AssocationPropertyInfo;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.DataTypePropertyInfo;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.RefDataTypePropertyInfo;
import java.util.HashMap;
import java.util.Map;

public class AssociationRepoProcessor extends  AbstractRepoPrcessor {

  @Override
  public Object readProperty(DbColumnInfo dbColumnInfo, DbProcessor dbProcessor,
      BaseAdaptorItem adaptorItem, ICefReader reader) {

    AssocationPropertyInfo associationInfo = (AssocationPropertyInfo) dbColumnInfo
        .getDataTypePropertyInfo().getObjectInfo();
    HashMap<String, String> map = getAssociationDbMapping(dbColumnInfo, adaptorItem);
    CefMappingReader mappingReader = new CefMappingReader(map, reader);
    EntityRelationalAdaptor adapter = ((BaseRootRepository) adaptorItem
        .getAssociation(dbColumnInfo.getDataTypePropertyInfo().getPropertyName())
        .getRefRepository()).getEntityDac(associationInfo.getAssociationInfo().getNodeCode())
        .getEntityAdaptor();
    try {
      AssoInfoBase data = (AssoInfoBase) associationInfo.getAssoType().newInstance();
      data.setValue(associationInfo.getAssociationInfo().getPrivateTargetColumn(), adapter
          .readProperty(associationInfo.getAssociationInfo().getPrivateSourceColumn(),
              mappingReader));
      for (Map.Entry<String, DataTypePropertyInfo> refPropertyInfo : associationInfo
          .getAssociationInfo().getRefPropInfos().entrySet()) {
        data.setValue(refPropertyInfo.getValue().getPropertyName(), adapter.readProperty(
            ((RefDataTypePropertyInfo) refPropertyInfo.getValue()).getRefPropertyName(),
            mappingReader));
      }
      return data;
    } catch (InstantiationException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  public Object readRefProperty(DbColumnInfo belongColumnInfo,BaseAdaptorItem baseAdaptorItem,ICefReader reader,String refPropertyName)
  {
    AssocationPropertyInfo associationInfo = (AssocationPropertyInfo) belongColumnInfo
            .getDataTypePropertyInfo().getObjectInfo();
    HashMap<String, String> map = getAssociationDbMapping(belongColumnInfo, baseAdaptorItem);
    CefMappingReader mappingReader = new CefMappingReader(map, reader);
    EntityRelationalAdaptor adapter = ((BaseRootRepository) baseAdaptorItem
            .getAssociation(belongColumnInfo.getDataTypePropertyInfo().getPropertyName())
            .getRefRepository()).getEntityDac(associationInfo.getAssociationInfo().getNodeCode())
            .getEntityAdaptor();

      return adapter.readProperty(refPropertyName,mappingReader);
//      AssoInfoBase data = (AssoInfoBase) associationInfo.getAssoType().newInstance();
//      data.setValue(associationInfo.getAssociationInfo().getPrivateTargetColumn(), adapter
//              .readProperty(associationInfo.getAssociationInfo().getPrivateSourceColumn(),
//                      mappingReader));
//      for (Map.Entry<String, DataTypePropertyInfo> refPropertyInfo : associationInfo
//              .getAssociationInfo().getRefPropInfos().entrySet()) {
//        data.setValue(refPropertyInfo.getValue().getPropertyName(), adapter.readProperty(
//                refPropertyName,
//                mappingReader));
//      }
//      return data;

  }
  @Override
  public Object getPropertyChangeValue(DbColumnInfo dbColumnInfo, Object value) {
    if(value==null)
      return null;
    IAuthFieldValue authFieldValue= (IAuthFieldValue) value;
    return authFieldValue.getValue();
  }

  @Override
  public Object getPersistenceValue(DbColumnInfo dbColumnInfo, Object value) {
    return dbColumnInfo.getTypeTransProcesser().transType(value);
  }

  private HashMap<String, String> getAssociationDbMapping(DbColumnInfo dbColumnInfo,BaseAdaptorItem adaptorItem) {
    AssocationPropertyInfo associationInfo = (AssocationPropertyInfo) dbColumnInfo
        .getDataTypePropertyInfo().getObjectInfo();
    return associationInfo.getAssDbMapping();
  }
}
